package com.jzo2o.es.core.operations;

import com.jzo2o.common.model.PageResult;
import com.jzo2o.common.model.dto.PageQueryDTO;
import co.elastic.clients.elasticsearch._types.query_dsl.MatchQuery;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.util.ObjectBuilder;

import java.util.List;
import java.util.function.Function;

/**
 * Elasticsearch文档操作接口，定义文档级别的CRUD及查询方法
 */
public interface DocumentOperations {

    // 新增单条文档
    <T> Boolean insert(String index, T document);
    // 批量新增文档
    <T> Boolean batchInsert(String index, List<T> documents);
    // 批量新增或更新文档（存在则更新，不存在则新增）
    <T> Boolean batchUpsert(String index, List<T> documents);
    // 根据ID更新文档（需保证文档对象中包含ID字段）
    <T> Boolean updateById(String index, T document);
    // 根据ID删除文档
    <ID> Boolean deleteById(String index, ID id);

    // 批量删除文档
    <ID> Boolean batchDelete(String index, List<ID> ids);
    // 根据ID查询文档
    <T, ID> T findById(String index, ID id, Class<T> clazz);
    // 根据ID列表批量查询文档
    <T, ID> List<T> findByIds(String index, List<ID> ids, Class<T> clazz);
    // 根据ID列表批量查询文档（指定返回字段）
    <T, ID> List<T> findByIds(String index, List<ID> ids, List<String> includes, Class<T> clazz);

    /**
     * 还未写完 todo
     */
    // 分页查询文档
    <T> PageResult<T> findForPage(PageQueryDTO pageQueryDTO, Class<T> targetClass);

    /**
     * 结合地理坐标范围检索文档
     * 先按条件筛选，再按地理距离过滤，最后支持排序
     *
     * @param index         文档所属索引名称
     * @param searchBuilder 基础查询条件构建器
     * @param locationName  地理坐标字段名
     * @param location      中心点坐标（格式："纬度,经度"）
     * @param distance      搜索半径（单位：米）
     * @param sortBy        排序字段（可为null，默认按距离排序）
     * @param isAsc         是否升序排序
     * @param size          返回结果数量
     * @param clazz         文档对象的类类型
     * @param <T>           文档对象类型
     * @return 符合条件的文档列表
     */
    <T> List<T> searchByWithGeo(String index,
                                SearchRequest.Builder searchBuilder,
                                String locationName,
                                String location,
                                double distance,
                                String sortBy,
                                Boolean isAsc,
                                int size,
                                Class<T> clazz);

    /**
     * 执行自定义搜索请求
     *
     * @param searchRequest 搜索请求对象
     * @param clazz         文档对象的类类型
     * @param <T>           文档对象类型
     * @return Elasticsearch原生搜索响应对象
     */
    <T> SearchResponse<T> search(SearchRequest searchRequest, Class<T> clazz);
}
